/**
 * bsw_event.h
 * 简单事件驱动模型类型及接口声明
 * 
 * 竹影半墙
 * 2023.09
 */
#ifndef BSW_EVENT_H
#define BSW_EVENT_H

#include "bsw_comm.h"
#include "bsw_lsit.h"
#include "bsw_event_auto.h"

typedef struct bsw_event        bsw_event_s;
typedef struct bsw_event_app    bsw_event_app_s;
typedef struct bsw_event_queue  bsw_event_queue_s;
typedef struct bsw_event_action bsw_event_action_s;
typedef int (*bsw_event_handle)(int fd, uint32_t events, void *data);

extern bsw_event_action_s * bsw_event_auto_action;

/**
 * 事件驱动模型实例参数
 * @events 事件内存预分配数
 * @works  事件处理工作线程数
 * @size   事件驱动大概容纳量
 */
struct bsw_event_app {
    int events;
    int works;
    int size;
};

/**
 * 事件描述
 * @id      事件唯一标识
 * @n_hash  用于串联哈希表的结点
 * @queued  是否已入队
 * @refcnt  引用计数
 * @n_queue 队列串联结点
 * @handle  事件处理回调
 * @fd      关联描述符
 * @data    处理私有数据
 * @reach   已检测到的事件类型
 * @waits   等待被检测的事件类型
 */
struct bsw_event {
    int fd;
    bsw_list_node_s n_hash_fd;

    uint64_t id;
    bsw_list_node_s n_hash_id;

    /**
     * 当读事件来临时是否关闭读事件出发
     */
    uint32_t readmulti:1;
    uint32_t queued:1;
    uint32_t refcnt;
    bsw_listd_node_s n_queue;

    bsw_event_handle handle;
    int fd;
    void *data;
    uint32_t waits;
    uint32_t reach;
};

/**
 * 事件模型支持的动作
 * @add 新增事件
 * @enqueue 就绪事件入队
 * @mod   事件修改
 * @del   事件删除
 * @init  事件驱动模型初始化
 * @close 事件驱动模型支撑关闭
 */
struct bsw_event_action {
    int  (*add)  (int fd, uint32_t events, uint64_t u64);
    int  (*enqueue)(bsw_event_queue_s *, int);
    int  (*mod)  (int fd, uint32_t events, uint64_t u64);
    int  (*del)  (int fd);
    int  (*init) (int);
    void (*close)(void);
};

/**
 * 事件驱动模型初始化与关闭
 * @app 实例化参数
 */
int  bsw_event_init(bsw_event_app_s *app);
void bsw_event_close(void);

/**
 * 事件新增、更改、删除
 * @fd 事件关联描述符
 * @events 类型类型 bsw_events_e
 * @data   事件关联数据
 */
int bsw_event_add(int fd, uint32_t events,
    bsw_event_handle handle, void *data);
int bsw_event_mod(int fd, uint32_t events, void *data);
int bsw_event_del(int fd);

/**
 * 事件入队头/尾部
 * @events 事件类型
 * @e 事件
 * @q 队列
 */
int bsw_event_enqueue_head(uint32_t events,
    bsw_event_s *e, bsw_event_queue_s *q);
inr bsw_event_enqueue_tail(uint32_t events,
    bsw_event_s *e, bsw_event_queue_s *q);

int bsw_event_mod_add(int fd, uint32_t events, void *data);
int bsw_event_mod_del(int fd, uint32_t events, void *data);

#endif